iT邦幫忙

2019 iT 邦幫忙鐵人賽

DAY 10
2
Modern Web

從0.5開始的JavaScript系列 第 10

Day10 工具包: 物件(1) - call by value、reference?

  • 分享至 

  • xImage
  •  

昨天整理了 Array 的相關方法,那今日來聊聊物件~

物件

格式

  1. 屬性: 值
var myObject = {
  name: 'Ryan'
};
console.log(myObject.name); // Ryan

myObject.age = 18;
console.log(myObject.age); // 18
  1. 也可以這樣寫,當一筆資料有 key 時,不想用陣列儲存,可以用這種方式:
var students = {};
students['Bob'] = {age: 18, sex: "male"};
students['Alice'] = {age: 17, sex: "female"};

console.log(students);
// {
//     Bob: {age: 18, sex: "male"},
//     Alice: {age: 17, sex: "female"}
// }

物件 & 陣列 & 函式

要執行函數要加()

var myObject = {
  teacher: 'Ken',
  student: ['A', 'B', 'C'],
  sayHi: function(){
    alert('Hi');
  }
};
myObject.sayHi(); // Hi

建構函式(函式 & 物件)

有寫過其他物件導向語言的應該會覺得很熟悉,

function circle(r){
  this.r = r;
  this.area = Math.PI * r * r;
  this.print = function(){
    console.log("radius = " + r);
  };
}

var ball = new circle(10);
ball.print(); // "radius = 10"

call by reference(sharing)

我們在 Day2 介紹了基本型別(Number、String、Boolean、null、undefined),它們屬於 call by value。而 Array、Objectcall by reference(sharing)

PS. 關於 call by reference、sharing 的深入討論有興去可以去查查,這邊就直接稱呼 call by reference。

call by value

那什麼是 call by value 呢?

可以看看這個範例,

  • ab 的值存放的記憶體位置不一樣,
    => 所以改動 b 不會影響到 a
var a = 123;
var b = a;
b = 456;
console.log(a); // 123
console.log(b); // 456

恩...看起來好像沒什麼特別,ab本來就不一樣。

call by reference

那請再看看這個範例,請問 Q1Q2 分別是多少?

var a = {value: 100};
var b = a;
b.value = 500;
console.log(a.value); // Q1=?
console.log(b.value); // Q2=?

想好了嘛,答案是,
Ans:
Q1 = 500
Q2 = 500

咦,為什麼我改動 b 的值,連帶影響到 a 的值了呢?

這就是 call by reference
JS 中的 Array、Object 都屬於這種特性,它們在傳遞時,是傳記憶體地址;而不是單純傳而已。

小故事

還是有點抽象嗎,那我再舉一個例子:
「我手上有一張白紙,上面寫了 100,那我再拿一張白紙,上面也寫 100,並把這張白紙送給你。試問,你在你的白紙上面把數字改成 1000,請問我的白紙上面數字會變成 1000 嗎?」

上方的例子是普通的兩個人進行示範,不是在看大衛魔術(X,所以我的白紙不會因為他更改他自己的白紙而影響到我的值。
這個概念就是 call by value,只有單純的對值做變動。

好了,那我再舉一個例子做說明:
「今天有個小偷A要闖空門偷東西,他手上有一張白紙寫著那間倒楣房子的地址。但是被同行B偷看到了那個地址,並決定下手為強,就先去把房子裡 100 萬的現金搬走,而小偷A晚上照著地址過去要偷東西時,發現房子已經被洗劫一空,當場痛哭失聲」

這只是舉例,請勿做出會讓家人傷心的事情(O,
那這個概念就是 call by reference,白紙上的地址導向的是那間房子,所以不管有幾張白紙上面都寫了那個地址,它們都是指向同一間房子,所以房子的錢被搬走,其他人來當然看不到那些被偷走的錢了。

回到上方的範例,所以 b = a,實際上 b 是指到 a 的記憶體位置,所以 a 和 b 指向的是同一個地址,更改 b 的值也會影響到 a 的值。

那再看看這個範例,請問 Q3 會印出 60 還是 100?

function addNum(tmp){
    tmp.grade += 40;
}
var student = {grade: 60};
addNum(student);

console.log(student.grade); // Q3=?

沒錯,答案是,
Ans:
Q3 = 100

因為函數傳遞的參數為物件時也是一樣的特性


明後兩天會聊聊深拷貝、淺拷貝,還有 ES6 對於物件的一些方法。

那今日的分享就到這,我們明天見/images/emoticon/emoticon51.gif


上一篇
Day9 工具包: Array(2)-延展、其餘、解構賦值
下一篇
Day11 工具包: 物件(2) - 深拷貝vs淺拷貝
系列文
從0.5開始的JavaScript30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言